﻿#region << 版 本 注 释 >>
/*----------------------------------------------------------------
// Copyright (C) 2021 kingerrobot
// 版权所有。 
//
// 文件名：BProdSkuProduct
// 文件功能描述：
//
// 创建者：名字 (zzl)
// 时间：2021/12/9 8:33:13
//
// 修改人：
// 时间：
// 修改说明：
// 版本：V1.0.0
//----------------------------------------------------------------*/
#endregion
using K8.MDCBB;
using KingerRobot.MexicoSailunWMS.Spi;
using Microsoft.EntityFrameworkCore.Internal;
using System;

//using MyBatis.DataMapper.TypeHandlers.Nullables;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace KingerRobot.MexicoSailunWMS.SpiService;

internal class BWcsScanner : IWcsScanner
{
    // 创建成功
    public int AddWcsScanner(long scannerLocId, string productCode, int scannerCount, string remark, int priority)
    {
        var db = Db.Default;
        var result = 0;
        //保证同一条码只插入一条
        if (db.WcsScanners.Where(t => t.Barcode == productCode && t.UseFlag == 1).FirstOrDefault() is null)
        {
            result = db.WcsScanners.Insert(new POWcsScanner
            {
                Id = XID.Nextval,
                StartLoc = scannerLocId,
                Barcode = productCode,
                RemarkMemo = remark,
                Priority = priority,
                ScannerCount = scannerCount,
            });
        }
        return result;
    }
    public List<POWcsScanner> GetWcsScannerListByDate(DateTime startTime, DateTime endTime)
    {
        var db = Db.Default;
        var result = db.WcsScanners.Where(t => t.CreateTime >= startTime && t.CreateTime < endTime).ToList();
        return result;
    }
    public List<WcsScannerGroupCount> GetScannerMaterialGroupByDate(DateTime startTime, DateTime endTime)
    {

        var db = Db.Default;
        var scannerMaterial = db.WcsScanners.Join(db.ProdProducts, f => f.Barcode, s => s.ProductCode, (f, s) => new
        {
            WcsScanners = f,
            s.MaterialId,
        }).Where(t => t.WcsScanners.CreateTime >= startTime && t.WcsScanners.CreateTime < endTime)
           .Join(db.ProdMaterials, f => f.MaterialId, s => s.Id, (f, s) => s)
           .GroupBy(t => t.MaterialCode).Select(t => new WcsScannerGroupCount
           {
               MaterialCode = t.Key,
               Count = t.Count()
           }).ToList();

        return scannerMaterial;
    }

    public int DeleWcsScannerByTaskId(long taskId, string remark)
    {

        var db = Db.Default;
        var scanners = db.WcsScanners.Where(t => t.TaskId == taskId).FirstOrDefault();
        if (scanners is not null)
        {
            scanners.UseFlag = 0;
            scanners.RemarkMemo = remark;
            scanners.UpdateTime = DateTime.Now;
        }
        db.SaveChanges();
        return 1;
    }



    //public List<POWcsScanner> GetNoTaskWcsScanner()
    //{
    //    //var db = Db.Default;
    //    //var result = db.WcsScanners.Where(t => t.Status == (int)EnumScannerStatus.NoCreate && t.UseFlag == 1)
    //    //    .OrderByDescending(t => t.Priority)
    //    //    .ThenBy(t => t.CreateTime).ToList();
    //    //return result;
    //    return null;
    //}

    public int UpdateWcsScannerStatusByProductCode(string productCode, int status, string remarkMemo, long taskId = 0)
    {
        var db = Db.Default;
        var result = db.WcsScanners
            .Where(t => t.Barcode == productCode)
            .Update(new POWcsScanner()
            {
                Status = status,
                StatusTime = DateTime.Now,
                RemarkMemo = remarkMemo,
                UpdateTime = DateTime.Now,
                TaskId = taskId,
            });
        return result;
    }

    public List<HourScannerCount> GetHourScannerCountByDate(string date)
    {
        var db = Db.Default;
        if (String.IsNullOrWhiteSpace(date))
        {
            return null;
        }
        DateTime.TryParse($"{date} 08:30:00", out var startTime);
        var result = new List<HourScannerCount>();
        for (var i = 1; i <= 24; i++)
        {
            var endTime = startTime.AddHours(1);
            var scanners = db.WcsScanners.Join(db.RcsLocations, f => f.StartLoc, s => s.Id, (f, s) => new
            {
                f.Barcode,
                f.Priority,
                f.CreateTime,
                s.LocName,

            }).Where(t => t.CreateTime >= startTime && t.CreateTime < endTime && t.Priority == 0)
               .GroupBy(t => t.LocName)
               .Select(t => new { LocName = t.Key, Count = t.Count() })
              .ToList().Select(t => new HourScannerCount
              {
                  ScannerName = t.LocName,
                  Hour = startTime.ToString("yyyy-MM-dd HH:mm"),
                  Count = t.Count,
              }).ToList();
            result.AddRange(scanners);
            startTime = startTime.AddHours(1);
        }
        return result;



    }


    public List<HourScannerCount> GetHourScannerCountByDateV2(string date)
    {
        var db = Db.Default;
        if (String.IsNullOrWhiteSpace(date))
        {
            return null;
        }
        DateTime.TryParse($"{date} 08:30:00", out var startTime);
        var result = new List<HourScannerCount>();
        for (var i = 1; i <= 24; i++)
        {
            var endTime = startTime.AddHours(1);
            var scanners = db.WcsScanners.Join(db.RcsLocations, f => f.StartLoc, s => s.Id, (f, s) => new
            {
                f.Barcode,
                f.Priority,
                f.CreateTime,
                s.LocName,

            }).Where(t => t.CreateTime >= startTime && t.CreateTime < endTime && t.Priority == 0)
               .GroupBy(t => t.LocName)
               .Select(t => new { LocName = t.Key, Count = t.Count() })
              .ToList().Select(t => new HourScannerCount
              {
                  ScannerName = t.LocName,
                  Hour = startTime.ToString("yyyy-MM-dd HH:mm"),
                  Count = t.Count,
              }).ToList();



            var allScanners = new HourScannerCount()
            {
                ScannerName = "总入库扫码数",
                Hour = startTime.ToString("yyyy-MM-dd HH:mm"),
                Count = scanners.Sum(t => t.Count),
            };

            var scannerSecs = db.WcsScannerSecs.Join(db.RcsLocations, f => f.StartLoc, s => s.Id, (f, s) => new
            {
                f.Barcode,
                f.Priority,
                f.CreateTime,
                s.LocName,
            }).Where(t => t.CreateTime >= startTime && t.CreateTime < endTime && t.Priority == 0)
              .GroupBy(t => t.LocName)
              .Select(t => new { LocName = t.Key, Count = t.Count() })
              .ToList().Select(t => new HourScannerCount
              {
                  ScannerName = t.LocName,
                  Hour = startTime.ToString("yyyy-MM-dd HH:mm"),
                  Count = t.Count,
              }).ToList();


            var scannerOuts = db.WcsOutScannerAfters.Join(db.RcsLocations, f => f.StartLoc, s => s.Id, (f, s) => new
            {
                f.Barcode,
                f.CreateTime,
                s.LocName,
            }).Where(t => t.CreateTime >= startTime && t.CreateTime < endTime)
              .GroupBy(t => t.LocName)
              .Select(t => new { LocName = t.Key, Count = t.Count() })
              .ToList().Select(t => new HourScannerCount
              {
                  ScannerName = t.LocName,
                  Hour = startTime.ToString("yyyy-MM-dd HH:mm"),
                  Count = t.Count,
              }).ToList();
            if (allScanners.Count + scanners.Count + scannerSecs.Count + scannerOuts.Count > 0)
            {

                result.Add(allScanners);
                result.AddRange(scanners);
                result.AddRange(scannerSecs);
                result.AddRange(scannerOuts);
            }
            startTime = startTime.AddHours(1);
        }
        return result;



    }


    public List<HourScannerCount> GetMinScannerCountByDateV2(string date)
    {
        var db = Db.Default;
        if (String.IsNullOrWhiteSpace(date))
        {
            return null;
        }
        DateTime.TryParse(date, out var startTime);
        var result = new List<HourScannerCount>();
        for (var i = 1; i <= 60; i++)
        {
            var endTime = startTime.AddMinutes(1);
            var scanners = db.WcsScanners.Join(db.RcsLocations, f => f.StartLoc, s => s.Id, (f, s) => new
            {
                f.Barcode,
                f.Priority,
                f.CreateTime,
                s.LocName,

            }).Where(t => t.CreateTime >= startTime && t.CreateTime < endTime && t.Priority == 0)
               .GroupBy(t => t.LocName)
               .Select(t => new { LocName = t.Key, Count = t.Count() })
              .ToList().Select(t => new HourScannerCount
              {
                  ScannerName = t.LocName,
                  Hour = startTime.ToString("yyyy-MM-dd HH:mm"),
                  Count = t.Count,
              }).ToList();



            var allScanners = new HourScannerCount()
            {
                ScannerName = "总入库扫码数",
                Hour = startTime.ToString("yyyy-MM-dd HH:mm"),
                Count = scanners.Sum(t => t.Count),
            };

            var scannerSecs = db.WcsScannerSecs.Join(db.RcsLocations, f => f.StartLoc, s => s.Id, (f, s) => new
            {
                f.Barcode,
                f.Priority,
                f.CreateTime,
                s.LocName,
            }).Where(t => t.CreateTime >= startTime && t.CreateTime < endTime && t.Priority == 0)
              .GroupBy(t => t.LocName)
              .Select(t => new { LocName = t.Key, Count = t.Count() })
              .ToList().Select(t => new HourScannerCount
              {
                  ScannerName = t.LocName,
                  Hour = startTime.ToString("yyyy-MM-dd HH:mm"),
                  Count = t.Count,
              }).ToList();


            var scannerOuts = db.WcsOutScannerAfters.Join(db.RcsLocations, f => f.StartLoc, s => s.Id, (f, s) => new
            {
                f.Barcode,
                f.CreateTime,
                s.LocName,
            }).Where(t => t.CreateTime >= startTime && t.CreateTime < endTime)
              .GroupBy(t => t.LocName)
              .Select(t => new { LocName = t.Key, Count = t.Count() })
              .ToList().Select(t => new HourScannerCount
              {
                  ScannerName = t.LocName,
                  Hour = startTime.ToString("yyyy-MM-dd HH:mm"),
                  Count = t.Count,
              }).ToList();
            if (allScanners.Count + scanners.Count + scannerSecs.Count + scannerOuts.Count > 0)
            {

                result.Add(allScanners);
                result.AddRange(scanners);
                result.AddRange(scannerSecs);
                result.AddRange(scannerOuts);
            }
            startTime = startTime.AddMinutes(1);
        }
        return result;



    }


    public List<OutScannerAfterBean> GetWcsOutScannerAfter(DateTime startTime, DateTime endTime)
    {
        var db = Db.Default;
        var result = db.WcsOutScannerAfters.Join(db.RcsLocations, f => f.StartLoc, s => s.Id, (f, s) => new
        {
            s.LocName,
            f.Id,
            f.UseFlag,
            f.CreateTime,
        }).Where(t => t.CreateTime >= startTime && t.CreateTime < endTime && t.UseFlag == 1)
          .GroupBy(t => t.LocName)
          .Select(t => new OutScannerAfterBean
          {
              ScannerName = t.Key,
              ScannerCount = t.Count()
          }).ToList();
        return result;
    }

    public List<ProductScannerRecord> GetProductScannerRecordByCode(string ProductCode)
    {

        var db = Db.Default;
        //入库一次扫描
        var data1 = db.WcsScanners.Join(db.RcsLocations, f => f.StartLoc, s => s.Id, (f, s) => new ProductScannerRecord
        {
            ProductCode = f.Barcode,
            ScannerTime = f.CreateTime ?? DateTime.MinValue,
            ScannerName = s.LocName,
        }).Where(t => t.ProductCode == ProductCode).ToList();
        //入库二次扫描
        var data2 = db.WcsScannerSecs.Join(db.RcsLocations, f => f.StartLoc, s => s.Id, (f, s) => new ProductScannerRecord
        {
            ProductCode = f.Barcode,
            ScannerTime = f.CreateTime ?? DateTime.MinValue,
            ScannerName = s.LocName,
        }).Where(t => t.ProductCode == ProductCode).ToList();
        //入库完成
        var data3 = db.ProdSkus.Join(db.BakWcsTasks, f => f.Id, s => s.SkuId, (f, s) => new
        {
            f.SkuCode,
            FinishTime = s.FinishTime ?? DateTime.MinValue,
            s.TargetLoc,
            s.TaskType,
            s.TaskStatus,
        }).Join(db.RcsLocations, f => f.TargetLoc, s => s.Id, (f, s) => new
        {

            f.SkuCode,
            f.FinishTime,
            s.LocName,
            f.TaskStatus,
            f.TaskType
        }).Where(t => t.SkuCode == ProductCode && t.TaskType == (int)EnumTaskType.Warehousing && t.TaskStatus == 9).Select(t => new ProductScannerRecord
        {
            ProductCode = t.SkuCode,
            ScannerTime = t.FinishTime,
            ScannerName = t.LocName,
        }).ToList();
        //出库扫描
        var data4 = db.WcsOutScannerAfters.Join(db.RcsLocations, f => f.StartLoc, s => s.Id, (f, s) => new ProductScannerRecord
        {
            ProductCode = f.Barcode,
            ScannerTime = f.CreateTime ?? DateTime.MinValue,
            ScannerName = s.LocName,
        }).Where(t => t.ProductCode == ProductCode).ToList();
        //出库ems任务完成
        var data5 = db.ProdSkus.Join(db.BakWcsTasks, f => f.Id, s => s.SkuId, (f, s) => new
        {
            f.SkuCode,
            FinishTime = s.FinishTime ?? DateTime.MinValue,
            s.TargetLoc,
            s.TaskType,
            s.TaskStatus,
        }).Join(db.RcsLocations, f => f.TargetLoc, s => s.Id, (f, s) => new
        {

            f.SkuCode,
            f.FinishTime,
            s.LocName,
            f.TaskStatus,
            f.TaskType
        }).Where(t => t.SkuCode == ProductCode && t.TaskType == (int)EnumTaskType.EMS && t.TaskStatus == 9).Select(t => new ProductScannerRecord
        {
            ProductCode = t.SkuCode,
            ScannerTime = t.FinishTime,
            ScannerName = t.LocName,
        }).ToList();
        var result = new List<ProductScannerRecord>();
        result = data1.Union(data2).Union(data3).Union(data4).Union(data5).OrderBy(t => t.ScannerTime).ToList();
        return result;
    }


    //// 修改扫描数量
    //public int UpdateLogScannerCountByProductCode(string productCode, long tireCount, int count)
    //{
    //    var db = Db.Default;
    //    var result = db.LogScanners
    //        .Where(t => t.Barcode == productCode && t.TireCount == tireCount && t.Status != (int)EnumScannerStatus.Execute)
    //        .Update( new()
    //        {
    //            ScannerCount = count
    //        });
    //    return result;
    //}

    //public POLogScanner GetLogScannerByProductCode(string productCode, long tireCount)
    //{
    //    var db = Db.Default;
    //    var result = db.LogScanners
    //        .Where(t => t.Barcode == productCode
    //        && t.TireCount == tireCount
    //        && t.Status != (int)EnumScannerStatus.Execute
    //        && t.Status != (int)EnumScannerStatus.Fail
    //        && t.Status != (int)EnumScannerStatus.Create)
    //        .FirstOrDefault();
    //    return result;
    //}

    //private POLogScanner GetLogScannerCreateByProductCode(string productCode, long tireCount)
    //{
    //    var db = Db.Default;
    //    var result = db.LogScanners
    //        .Where(t => t.Barcode == productCode
    //        && t.TireCount == tireCount
    //        && t.Status == (int)EnumScannerStatus.Create)
    //        .FirstOrDefault();
    //    return result;
    //}
    //public POLogScanner GetLogScannerNoExecuteByProductCode(string productCode, long tireCount)
    //{
    //    var db = Db.Default;
    //    var result = db.LogScanners
    //        .Where(t => t.Barcode == productCode
    //        && t.TireCount == tireCount
    //        && t.Status != (int)EnumScannerStatus.Execute)
    //        .FirstOrDefault();
    //    return result;
    //}



    //// 执行成功
    //public int UpdateLogScannerSuccessByProductCode(string productCode, long tireCount, int status)
    //{
    //    var db = Db.Default;
    //    var result = db.LogScanners
    //        .Where(t => t.Barcode == productCode
    //        && t.TireCount == tireCount
    //        && t.Status != (int)EnumScannerStatus.Execute)
    //        .Update( new()
    //        {
    //            Status = status,
    //            UpdateTime = DateTime.Now,
    //        });
    //    return result;
    //}
    //// 执行成功
    //public int UpdateLogScannerSuccessByProductCodeV2(string productCode, int status)
    //{
    //    var db = Db.Default;
    //    var result = db.LogScanners
    //        .Where(t => t.Barcode == productCode
    //        && t.Status == (int)EnumScannerStatus.Success)
    //        .Update( new()
    //        {
    //            Status = status,
    //            UpdateTime = DateTime.Now,
    //        });
    //    return result;
    //}
}
